package net.sevear.chaos.recommend
{
	import com.adobe.serialization.json.JSON;
	import com.douban.auth.DBAuthenticate;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.TimerEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	import flash.utils.Timer;
	
	import mx.collections.ArrayCollection;
	
	import net.sevear.chaos.douban.DBShuoManager;
	import net.sevear.chaos.download.DBRadioKeeper;
	import net.sevear.chaos.download.Predef;
	import net.sevear.chaos.event.HasNewChaosEvent;
	import net.sevear.chaos.event.RecommendEvent;
	import net.sevear.chaos.utils.DataUtil;
	import net.sevear.chaos.vo.RecommendInfo;
	import net.sevear.chaos.vo.TrackInfo;
	
	public class ChaosEvtManager extends EventDispatcher
	{
		public static const TYPE_GET_NEW_RECOMMENDS_REPONSES:int 	= 1002;
		public static const TYPE_ADDED_AS_DEST_ID:int 				= 1003;
		public static const TYPE_INVITED_UID_ACTTIVATE:int      	= 1005;
		public static const TYPE_P2PSITE_OPEN:int 					= 1007;
		
		public static const ACCEPTABLE_EVENTS:Array = [
			TYPE_GET_NEW_RECOMMENDS_REPONSES,
			TYPE_ADDED_AS_DEST_ID,
			TYPE_INVITED_UID_ACTTIVATE,
			TYPE_P2PSITE_OPEN];
		
		private static const MAX_NEWS_LIST:int = 10;
		private static const MIN_REQUEST_INTERNAL:int = 10;
		
		public static const EVENT_URL:String = "/e/";
		
		private var newsLoader:URLLoader;
		private var rst:URLRequest;
		private var isRequesting:Boolean;
		private var timer:Timer;
		private var _intervalSec:int=MIN_REQUEST_INTERNAL;
		private var holdtimes:int;
		private var utctime:int;
		public function ChaosEvtManager(target:IEventDispatcher=null)
		{
			super(target);
			newsLoader = new URLLoader();
			newsLoader.addEventListener(Event.COMPLETE,onGetNews);
			newsLoader.addEventListener(IOErrorEvent.IO_ERROR,onIOError);

			rst = new URLRequest();
			rst.url = Predef.CHAOS_HOST+EVENT_URL;
			rst.method = URLRequestMethod.GET;
			
			_intervalSec = 20;
			timer = new Timer(_intervalSec*1000);
			timer.addEventListener(TimerEvent.TIMER,onTimer);
			
			utctime = 0;
		}
		
		
		public function set interval(value:int):void{
			if(value>=MIN_REQUEST_INTERNAL){
				_intervalSec = interval;
			}
		}
		
		public function get interval():int{
			return _intervalSec;
		}
		
		
		public function start():void{
			if(timer.running==false)
			{
				var vars:URLVariables = new URLVariables();
				vars.uid=DBAuthenticate.getInstance().dbUID;
				vars.time = utctime;
				rst.data = vars;
				timer.start();
			}
				
			else{
				trace("event has started");
			}
		}
		
		public function stop():void{
			if(timer.running==true)
				timer.stop();
			else{
				trace("event has stopped");
			}
		}
		
		public function restart():void{
			
		}
		
		private function onTimer(e:TimerEvent):void{
			if(isRequesting == false){
				isRequesting = true;
				var vars:URLVariables = new URLVariables();
				vars.uid=DBAuthenticate.getInstance().dbUID;
				vars.time = utctime;
				rst.data = vars;
				newsLoader.load(rst);
			}else{
				if(holdtimes<3){
					holdtimes++;
				}else{
					holdtimes = 0;
					trace("Chaos Evt Manager Time out");
					isRequesting = false;
				}
				trace("another event request has been sent and have not gotten any reponse.");
			}
			
			DBShuoManager.getInstance().getBootData();
		}
		/**
		 * {recommends:[],remainReCount:0,
		 * events:{}}
		 * */
		private function onGetNews(e:Event):void{
			isRequesting = false;
			holdtimes = 0;
			var rstStr:String = (e.currentTarget as URLLoader).data as String;
			var reJsonObj:Object = JSON.decode(rstStr);
			var recommends:Array = reJsonObj.recommends as Array;
			parseRecommendList(recommends);
			var evs:Object = JSON.decode(reJsonObj.events as String);
			for each(var acceptableID:int in ACCEPTABLE_EVENTS){
				if(evs.hasOwnProperty(acceptableID.toString())){
					dispatchEvent(new HasNewChaosEvent(acceptableID,evs[acceptableID.toString()]));
				}
			}
		}
		
		private function parseRecommendList(recommends:Array):void{
			var recommendInfo:RecommendInfo;
			var uid:int = DBAuthenticate.getInstance().dbUID;
			var list:ArrayCollection = new ArrayCollection();
			if(recommends.length>0){
				for each(var reStr:String in recommends){
					var songObj:Object = JSON.decode(reStr);
					recommendInfo = new RecommendInfo();
					recommendInfo.id = songObj.id;
					recommendInfo.time = new Date((songObj.time as Number)*1000);
					if((songObj.time as Number)>utctime) 
						utctime = (songObj.time);
					recommendInfo.destUID = uid;
					recommendInfo.sourceUID = songObj.sourceUID;
					recommendInfo.sourceName = songObj.sourceName;
					recommendInfo.sourceURL = songObj.sourceURL;
					recommendInfo.sourceAlias = songObj.sourceAlias as String;
					var song:Object = JSON.decode(songObj.trackInfo);
					recommendInfo.trackInfo = new TrackInfo();
					DataUtil.parseChaosRecommendTrackInfo(song,recommendInfo.trackInfo);
					
					list.addItem(recommendInfo);
				}
				var e:RecommendEvent = new RecommendEvent(RecommendEvent.GET_NEW_RECOMMENDLIST,list);
				dispatchEvent(e);
			}
		}
		
		private function onIOError(e:IOErrorEvent):void{
			
		}
	}
}